type shouldDargHandel = () => boolean

/**
 * elm [必须] ： 允许任意拖拽的元素
 * shouldDargHandel [可选] ： 是否允许拖拽的自定义逻辑处理函数，返回true允许拖拽，返回false不允许拖拽
 * 
 * tips：防止意外，您应该知道，内部使用transform属性，来进行的位置移动。
 */
export function useDrag(elm: HTMLElement, shouldDargHandel?: shouldDargHandel){

    function Darg (elm: HTMLElement, shouldDargHandel?: shouldDargHandel){
        if(typeof shouldDargHandel === 'function'){
            this.shouldDarg = shouldDargHandel
        }
        this.addEvent();
        this.startX = 0;
        this.startY = 0;
        this.offsetX = 0;
        this.offsetY = 0;
        this.translateX = 0;
        this.translateY = 0;
        this.flag = false;
    }
    /*
    * return true 允许拖拽
    * return false 不允许拖拽
    */
    Darg.prototype.shouldDarg = function(){
        var styles = window.getComputedStyle(elm);
        var top = parseInt(styles.top) + this.offsetY+ this.translateY;
        var left = parseInt(styles.left) + this.offsetX + this.translateX;
        return top < window.innerHeight &&
            top > -parseInt(styles.height) &&
            left < window.innerWidth &&
            left > -parseInt(styles.width);
    }
    Darg.prototype.getOffset = function(){
        var touch = event.touches ? event.touches[0] : event;
        return { x: touch.clientX, y: touch.clientY }
    }
    Darg.prototype.addEvent = function(){
        elm.style.position = "fixed";
        elm.style.zIndex = "100";
        elm.style.cursor = "pointer";
        elm.style.transitionDuration = "300ms";
        elm.style.transitionProperty = "transform";
        elm.addEventListener("mousedown", this.start.bind(this), false);
        elm.addEventListener("touchstart", this.start.bind(this), false);
        elm.addEventListener("mousemove", this.move.bind(this), false);
        elm.addEventListener("touchmove", this.move.bind(this), false);
        elm.addEventListener("mouseleave", this.end.bind(this), false);
        elm.addEventListener("mouseup", this.end.bind(this), false);
        elm.addEventListener("touchend", this.end.bind(this), false);
    }
    Darg.prototype.start = function(){
        this.startX = this.getOffset().x;
        this.startY = this.getOffset().y;
        elm.style.transitionDuration = "0ms";
        this.flag = true;
    }
    Darg.prototype.move = function(){
        if(!this.flag) return;
        this.offsetX = this.getOffset().x - this.startX;
        this.offsetY = this.getOffset().y - this.startY;
        elm.style.transform = ['translate3d(', this.offsetX + this.translateX, 'px,', this.offsetY+ this.translateY, 'px,', '0)'].join("");
        event?.stopPropagation();
        event.preventDefault();
        return false;
    }
    Darg.prototype.end = function(){
        if(!this.flag) return;
        this.flag = false;
        if(this.shouldDarg()){
            this.translateX += this.offsetX;
            this.translateY += this.offsetY;
        }else{
            elm.style.transitionDuration = "300ms";
        }
        elm.style.transform = ['translate3d(', this.translateX, 'px,', this.translateY, 'px,', '0)'].join("");
    }

    return new Darg(elm, shouldDargHandel)
};